#pragma once

#include <assert.h>
namespace FreeListModule
{
    //自由链表的管理
    class FreeList
    {
    public:
        void Push(void*& obj)
        {
            //头插法
            *((void**)obj) = _freelist;
            _freelist = obj;
            _size++;
        }
        void Push(void*& start, void*& end, size_t num)
        {
            *((void**)end) = _freelist;
            _freelist = start;
            _size += num;
        }
        void* Pop()
        {
            //头删法
            assert(_freelist);

            void* obj = _freelist;
            _freelist = *((void**)_freelist);
            _size--;
            return obj;
        }
        void Pop(void*& begin, void*& end, size_t num)
        {
            //取出num个内存单元返回
            begin = _freelist;
            end = begin;
            for (int i = 0; i < num - 1; i++)
            {
                end = *(void**)end;
            }
            _freelist = *(void**)end;
            *(void**)end = nullptr;

            _size -= num;
        }
        bool Empty()
        {
            return _freelist == nullptr;
        }
        size_t& Count()
        {
            return _count;
        }
        size_t Size()
        {
            return _size;
        }
    private:
        size_t _count = 1;                  //慢增长次数
        size_t _size = 0;                   //实际个数
        void* _freelist = nullptr;        //自由链表
    };
}